#include "input.hpp"

void SimulationParams::readOp(std::string str,matrix<double> *mat){
  //Create buffer
  std::ostringstream ostr;
  ostr<<"["<<Dim<<","<<Dim<<"]"<<str;
  //Input stream 
  std::istringstream is(ostr.str());
  is >> *mat;
}

void SimulationParams::readVec(std::string str,vector<std::complex<double> > *vec){
  //Create buffer
  std::ostringstream ostr;
  ostr<<"["<<Dim<<"]"<<str;
  //Input stream 
  std::istringstream is(ostr.str());
  is >> *vec;
}

void JumpOp::readOp(std::string str,matrix<double> *mat){
  //Create buffer
  std::ostringstream ostr;
  ostr<<"["<<Dim<<","<<Dim<<"]"<<str;
  //Input stream 
  std::istringstream is(ostr.str());
  is >> *mat;
}

JumpOp::JumpOp(ticpp::Iterator<ticpp::Element> elem){
  this->AnalyticRate=elem->GetAttribute<std::string>("AnalyticRate");
  this->Type=elem->GetAttribute<std::string>("Type");
  this->Tag=elem->GetAttribute<std::string>("Tag");
  this->Dim=elem->GetAttribute<int>("Dim");
  readOp(elem->GetAttribute<std::string>("Op"),&Op);
  //Params;
  ticpp::Element *el=elem->FirstChildElement("params");
  ticpp::Iterator<ticpp::Attribute> iattr;
  for(iattr=iattr.begin(el);iattr != iattr.end();iattr++){
    Params[iattr->Name()]=atof(iattr->Value().c_str());
  }
}

SimulationParams::SimulationParams(const std::string &filename){
  try{
    //Open input file
    ticpp::Document doc(filename);
    doc.LoadFile();
    //Root Node 
    ticpp::Node* root=doc.FirstChildElement("InputFile");
    //Iterate through all children nodes
    ticpp::Iterator<ticpp::Element> child;
    for(child=child.begin(root);child != child.end();child++){
      std::string str;
      std::string inarray;
      child->GetValue(&str);
      
      if(str=="SimulationParams"){
	
	this->Time=child->GetAttribute<double>("Time");
	this->TimeStep=child->GetAttribute<int>("TimeStep");
	this->OutputStep=child->GetAttribute<int>("OutputStep");
	this->EnsembleSize=child->GetAttribute<int>("EnsembleSize");
      
      }
      
      else if(str=="System"){
	
	this->Dim=child->GetAttribute<int>("Dim");
	this->mixed=child->GetAttribute<std::string>("mixed");
	this->NumOfChannels=child->GetAttribute<int>("NumOfChannels");
	//Read Basis
	readOp(child->GetAttribute<std::string>("Op"),&Basis);
	//Read Initial state
	readVec(child->GetAttribute<std::string>("InitialState"),&InitialState);
	//Iterate childrens
	ticpp::Iterator<ticpp::Element> it_JumpOp;
	for(it_JumpOp = it_JumpOp.begin(root->FirstChildElement(str));it_JumpOp != it_JumpOp.end();it_JumpOp++){
	  JumpOperators.push_back(JumpOp(it_JumpOp));
	}
      
      }
      
      else if(str=="Output"){
	
	this->EnsembleOut=child->GetAttribute<std::string>("EnsembleOut");
	this->PDistOut=child->GetAttribute<std::string>("PDistOut");
	this->RhoOut=child->GetAttribute<std::string>("RhoOut");
	this->VarOut=child->GetAttribute<std::string>("VarOut");
	ticpp::Iterator<ticpp::Element> it_el("LambRate");
      	for(it_el = it_el.begin(root->FirstChildElement(str));it_el != it_el.end();it_el++){
      	  LambRatesOut[it_el->GetAttribute<int>("Tag")]=it_el->GetAttribute<std::string>("File");
	}
	
      	ticpp::Iterator<ticpp::Element> it_el2("DecRate");
      	for(it_el2 = it_el2.begin(root->FirstChildElement(str));it_el2 != it_el2.end();it_el2++){
      	  DecRatesOut[it_el2->GetAttribute<int>("Tag")]=it_el2->GetAttribute<std::string>("File");
      	}

      
      }
      
      else{
	continue;
      }
    }
    
    
    //Get "simple" types first, e.g. int,double,string etc.
    
  


  }
  catch(ticpp::Exception& ex){
    std::cout<<ex.what()<<std::endl;
  }
}


